#!/usr/bin/python
# coding=utf-8
###############################################################################

from test import CollectorTestCase
from test import get_collector_config
from test import unittest
from mock import Mock
from mock import patch

from diamond.collector import Collector

from varnish import VarnishCollector

###############################################################################


class TestVarnishCollector(CollectorTestCase):

    def setUp(self):
        config = get_collector_config('VarnishCollector', {})

        self.collector = VarnishCollector(config, None)

    def test_import(self):
        self.assertTrue(VarnishCollector)

    @patch.object(Collector, 'publish')
    def test_should_work_with_real_data_3_dot_0(self, publish_mock):
        collector_mock = patch.object(VarnishCollector, 'poll', Mock(
            return_value=self.getFixture('3.0/varnish_stats').getvalue()))
        collector_mock.start()
        self.collector.collect()
        collector_mock.stop()

        metrics = {
            'client_conn': 10799,
            'client_drop': 0,
            'client_req': 10796,
            'cache_hit': 6580,
            'cache_hitpass': 0,
            'cache_miss': 2566,
            'backend_conn': 13363,
            'backend_unhealthy': 0,
            'backend_busy': 0,
            'backend_fail': 0,
            'backend_reuse': 0,
            'backend_toolate': 0,
            'backend_recycle': 0,
            'backend_retry': 0,
            'fetch_head': 0,
            'fetch_length': 12986,
            'fetch_chunked': 0,
            'fetch_eof': 0,
            'fetch_bad': 0,
            'fetch_close': 331,
            'fetch_oldhttp': 0,
            'fetch_zero': 0,
            'fetch_failed': 0,
            'fetch_1xx': 0,
            'fetch_204': 0,
            'fetch_304': 45,
            'n_sess_mem': 19,
            'n_sess': 1,
            'n_object': 9,
            'n_vampireobject': 0,
            'n_objectcore': 17,
            'n_objecthead': 27,
            'n_waitinglist': 10,
            'n_vbc': 1,
            'n_wrk': 10,
            'n_wrk_create': 10,
            'n_wrk_failed': 0,
            'n_wrk_max': 11451,
            'n_wrk_lqueue': 0,
            'n_wrk_queued': 0,
            'n_wrk_drop': 0,
            'n_backend': 4,
            'n_expired': 2557,
            'n_lru_nuked': 0,
            'n_lru_moved': 5588,
            'losthdr': 0,
            'n_objsendfile': 0,
            'n_objwrite': 2546,
            'n_objoverflow': 0,
            's_sess': 10798,
            's_req': 10796,
            's_pipe': 0,
            's_pass': 10796,
            's_fetch': 13362,
            's_hdrbytes': 4764593,
            's_bodybytes': 23756354,
            'sess_closed': 10798,
            'sess_pipeline': 0,
            'sess_readahead': 0,
            'sess_linger': 0,
            'sess_herd': 0,
            'shm_records': 1286246,
            'shm_writes': 102894,
            'shm_flushes': 0,
            'shm_cont': 0,
            'shm_cycles': 0,
            'sms_nreq': 0,
            'sms_nobj': 0,
            'sms_nbytes': 0,
            'sms_balloc': 0,
            'sms_bfree': 0,
            'backend_req': 13363,
            'n_vcl': 1,
            'n_vcl_avail': 1,
            'n_vcl_discard': 0,
            'n_ban': 1,
            'n_ban_add': 1,
            'n_ban_retire': 0,
            'n_ban_obj_test': 0,
            'n_ban_re_test': 0,
            'n_ban_dups': 0,
            'hcb_nolock': 9146,
            'hcb_lock': 2379,
            'hcb_insert': 2379,
            'esi_errors': 0,
            'esi_warnings': 0,
            'accept_fail': 0,
            'client_drop_late': 0,
            'uptime': 35440,
            'dir_dns_lookups': 0,
            'dir_dns_failed': 0,
            'dir_dns_hit': 0,
            'dir_dns_cache_full': 0,
            'n_gzip': 8277,
            'n_gunzip': 11982,
        }

        self.setDocExample(collector=self.collector.__class__.__name__,
                           metrics=metrics,
                           defaultpath=self.collector.config['path'])
        self.assertPublishedMany(publish_mock, metrics)

    @patch.object(Collector, 'publish')
    def test_should_work_with_real_data_4_dot_0(self, publish_mock):
        collector_mock = patch.object(VarnishCollector, 'poll', Mock(
            return_value=self.getFixture('4.0/varnish_stats').getvalue()))
        collector_mock.start()
        self.collector.collect()
        collector_mock.stop()

        metrics = {
            'MAIN.uptime': 851,
            'MAIN.sess_conn': 3013382,
            'MAIN.sess_drop': 0,
            'MAIN.sess_fail': 0,
            'MAIN.sess_pipe_overflow': 0,
            'MAIN.client_req_400': 17,
            'MAIN.client_req_411': 0,
            'MAIN.client_req_413': 0,
            'MAIN.client_req_417': 0,
            'MAIN.client_req': 4089775,
            'MAIN.cache_hit': 2341983,
            'MAIN.cache_hitpass': 154893,
            'MAIN.cache_miss': 1300621,
            'MAIN.backend_conn': 4499,
            'MAIN.backend_unhealthy': 0,
            'MAIN.backend_busy': 0,
            'MAIN.backend_fail': 0,
            'MAIN.backend_reuse': 2419103,
            'MAIN.backend_toolate': 0,
            'MAIN.backend_recycle': 2419604,
            'MAIN.backend_retry': 13,
            'MAIN.fetch_head': 25,
            'MAIN.fetch_length': 702690,
            'MAIN.fetch_chunked': 1216071,
            'MAIN.fetch_eof': 0,
            'MAIN.fetch_bad': 0,
            'MAIN.fetch_close': 137,
            'MAIN.fetch_oldhttp': 0,
            'MAIN.fetch_zero': 0,
            'MAIN.fetch_1xx': 0,
            'MAIN.fetch_204': 0,
            'MAIN.fetch_304': 504930,
            'MAIN.fetch_failed': 0,
            'MAIN.fetch_no_thread': 0,
            'MAIN.pools': 2,
            'MAIN.threads': 4000,
            'MAIN.threads_limited': 0,
            'MAIN.threads_created': 4000,
            'MAIN.threads_destroyed': 0,
            'MAIN.threads_failed': 0,
            'MAIN.thread_queue_len': 0,
            'MAIN.busy_sleep': 1193,
            'MAIN.busy_wakeup': 1193,
            'MAIN.sess_queued': 0,
            'MAIN.sess_dropped': 0,
            'MAIN.n_object': 1120124,
            'MAIN.n_vampireobject': 0,
            'MAIN.n_objectcore': 1120528,
            'MAIN.n_objecthead': 1176948,
            'MAIN.n_waitinglist': 1380,
            'MAIN.n_backend': 2,
            'MAIN.n_expired': 180652,
            'MAIN.n_lru_nuked': 0,
            'MAIN.n_lru_moved': 1552209,
            'MAIN.losthdr': 0,
            'MAIN.s_sess': 3013384,
            'MAIN.s_req': 4089779,
            'MAIN.s_pipe': 0,
            'MAIN.s_pass': 352238,
            'MAIN.s_fetch': 1652859,
            'MAIN.s_synth': 94934,
            'MAIN.s_req_hdrbytes': 4784250600,
            'MAIN.s_req_bodybytes': 52901418,
            'MAIN.s_resp_hdrbytes': 2508258336,
            'MAIN.s_resp_bodybytes': 16343773348,
            'MAIN.s_pipe_hdrbytes': 0,
            'MAIN.s_pipe_in': 0,
            'MAIN.s_pipe_out': 0,
            'MAIN.sess_closed': 58799,
            'MAIN.sess_closed_err': 6412,
            'MAIN.sess_pipeline': 53,
            'MAIN.sess_readahead': 17,
            'MAIN.sess_herd': 4924320,
            'MAIN.shm_records': 630017674,
            'MAIN.shm_writes': 162187536,
            'MAIN.shm_flushes': 133825475,
            'MAIN.shm_cont': 6593666,
            'MAIN.shm_cycles': 472,
            'MAIN.sms_nreq': 0,
            'MAIN.sms_nobj': 0,
            'MAIN.sms_nbytes': 0,
            'MAIN.sms_balloc': 0,
            'MAIN.sms_bfree': 0,
            'MAIN.backend_req': 2423591,
            'MAIN.n_vcl': 1,
            'MAIN.n_vcl_avail': 1,
            'MAIN.n_vcl_discard': 0,
            'MAIN.bans': 1,
            'MAIN.bans_completed': 1,
            'MAIN.bans_obj': 0,
            'MAIN.bans_req': 0,
            'MAIN.bans_added': 1,
            'MAIN.bans_deleted': 0,
            'MAIN.bans_tested': 0,
            'MAIN.bans_obj_killed': 0,
            'MAIN.bans_lurker_tested': 0,
            'MAIN.bans_tests_tested': 0,
            'MAIN.bans_lurker_tests_tested': 0,
            'MAIN.bans_lurker_obj_killed': 0,
            'MAIN.bans_dups': 0,
            'MAIN.bans_lurker_contention': 0,
            'MAIN.bans_persisted_bytes': 13,
            'MAIN.bans_persisted_fragmentation': 0,
            'MAIN.n_purges': 0,
            'MAIN.n_obj_purged': 0,
            'MAIN.exp_mailed': 2842439,
            'MAIN.exp_received': 2842439,
            'MAIN.hcb_nolock': 3797501,
            'MAIN.hcb_lock': 1266489,
            'MAIN.hcb_insert': 1266484,
            'MAIN.esi_errors': 0,
            'MAIN.esi_warnings': 0,
            'MAIN.vmods': 2,
            'MAIN.n_gzip': 0,
            'MAIN.n_gunzip': 1809822,
            'MAIN.vsm_free': 972304,
            'MAIN.vsm_used': 83962304,
            'MAIN.vsm_cooling': 0,
            'MAIN.vsm_overflow': 0,
            'MAIN.vsm_overflowed': 0,
            'MGT.uptime': 851,
            'MGT.child_start': 1,
            'MGT.child_exit': 0,
            'MGT.child_stop': 0,
            'MGT.child_died': 0,
            'MGT.child_dump': 0,
            'MGT.child_panic': 0,
            'LCK.sms.creat': 0,
            'LCK.sms.destroy': 0,
            'LCK.sms.locks': 0,
            'LCK.smp.creat': 0,
            'LCK.smp.destroy': 0,
            'LCK.smp.locks': 0,
            'LCK.sma.creat': 2,
            'LCK.sma.destroy': 0,
            'LCK.sma.locks': 8079812,
            'LCK.smf.creat': 0,
            'LCK.smf.destroy': 0,
            'LCK.smf.locks': 0,
            'LCK.hsl.creat': 0,
            'LCK.hsl.destroy': 0,
            'LCK.hsl.locks': 0,
            'LCK.hcb.creat': 1,
            'LCK.hcb.destroy': 0,
            'LCK.hcb.locks': 1430122,
            'LCK.hcl.creat': 0,
            'LCK.hcl.destroy': 0,
            'LCK.hcl.locks': 0,
            'LCK.vcl.creat': 1,
            'LCK.vcl.destroy': 0,
            'LCK.vcl.locks': 4852573,
            'LCK.sessmem.creat': 0,
            'LCK.sessmem.destroy': 0,
            'LCK.sessmem.locks': 0,
            'LCK.sess.creat': 3011371,
            'LCK.sess.destroy': 2995725,
            'LCK.sess.locks': 154803,
            'LCK.wstat.creat': 1,
            'LCK.wstat.destroy': 0,
            'LCK.wstat.locks': 10626608,
            'LCK.herder.creat': 0,
            'LCK.herder.destroy': 0,
            'LCK.herder.locks': 0,
            'LCK.wq.creat': 3,
            'LCK.wq.destroy': 0,
            'LCK.wq.locks': 24257096,
            'LCK.objhdr.creat': 1266966,
            'LCK.objhdr.destroy': 90130,
            'LCK.objhdr.locks': 40326652,
            'LCK.exp.creat': 1,
            'LCK.exp.destroy': 0,
            'LCK.exp.locks': 10787337,
            'LCK.lru.creat': 2,
            'LCK.lru.destroy': 0,
            'LCK.lru.locks': 7418755,
            'LCK.cli.creat': 1,
            'LCK.cli.destroy': 0,
            'LCK.cli.locks': 297,
            'LCK.ban.creat': 1,
            'LCK.ban.destroy': 0,
            'LCK.ban.locks': 3025891,
            'LCK.vbp.creat': 1,
            'LCK.vbp.destroy': 0,
            'LCK.vbp.locks': 1705,
            'LCK.backend.creat': 2,
            'LCK.backend.destroy': 0,
            'LCK.backend.locks': 4852203,
            'LCK.vcapace.creat': 1,
            'LCK.vcapace.destroy': 0,
            'LCK.vcapace.locks': 0,
            'LCK.nbusyobj.creat': 0,
            'LCK.nbusyobj.destroy': 0,
            'LCK.nbusyobj.locks': 0,
            'LCK.busyobj.creat': 2423785,
            'LCK.busyobj.destroy': 2423780,
            'LCK.busyobj.locks': 20093877,
            'LCK.mempool.creat': 6,
            'LCK.mempool.destroy': 0,
            'LCK.mempool.locks': 22218269,
            'LCK.vxid.creat': 1,
            'LCK.vxid.destroy': 0,
            'LCK.vxid.locks': 1385,
            'LCK.pipestat.creat': 1,
            'LCK.pipestat.destroy': 0,
            'LCK.pipestat.locks': 0,
        }

        self.setDocExample(collector=self.collector.__class__.__name__,
                           metrics=metrics,
                           defaultpath=self.collector.config['path'])
        self.assertPublishedMany(publish_mock, metrics)

    @patch.object(Collector, 'publish')
    def test_should_fail_gracefully(self, publish_mock):
        collector_mock = patch.object(VarnishCollector, 'poll', Mock(
            return_value=self.getFixture(
                'varnish_stats_blank').getvalue()))
        collector_mock.start()
        self.collector.collect()
        collector_mock.stop()

        self.assertPublishedMany(publish_mock, {})

###############################################################################
if __name__ == "__main__":
    unittest.main()
